<?php
/**
 * 用户管理
 * @author xiegaolei
 * #1获取用户openid
 * #2获取授权用户信息
 * #3创建用户组
 * #4查询所有分组
 * #5修改分组
 * #6移动用户分组
 * #7批量移动用户分组
 * #8删除用户分组
 * #9用户设备注名
 * #10获取指定用户的详细信息
 * #11获取关注者列表
 */

class User extends Wechat {
    
    private $requestCodeURL = 'https://open.weixin.qq.com/connect/oauth2/authorize';
    private $oauthApiURL = 'https://api.weixin.qq.com/sns';
    /**
     * 构造方法，调用微信高级接口时实例化SDK
     * @param string $appid  微信appid
     * @param string $secret 微信appsecret
     */
    public function __construct($appid, $secret){
        parent::__construct($appid, $secret);
        //自定初始化
    }
    
    
    /**
     * 获取生成code地址
     * [getRequestCodeURL ]
     * @param string $redirect_uri
     * @param string $state
     * @param string $scope
     */
    public function getRequestCodeURL($redirect_uri, $state = null , $scope = 'snsapi_userinfo'){
        
        $query = array(
            'appid'         => $this->appId,
            'redirect_uri'  => $redirect_uri,
            'response_type' => 'code',
            'scope'         => $scope,
        );

        if(!is_null($state) && preg_match('/[a-zA-Z0-9]+/', $state)){
            $query['state'] = $state;
        }

        $query = http_build_query($query);
        return "{$this->requestCodeURL}?{$query}#wechat_redirect";
    }
    
    /**
     * 根据code获取access_token，用于后续接口访问
     * @return array access_token信息，包含 token 和有效期
     */
    public function getAccessTokenByCode($code){
    
        if (empty($code)){
            throw new Exception('code不能为空！');
        }
    
        $param = array(
            'appid'         => $this->appId,
            'secret'        => $this->appSecret,
            'code'          => $code,
            'grant_type'    => 'authorization_code'
        );
         
        $url = "{$this->oauthApiURL}/oauth2/access_token";
    
        $res = $this->http($url, $param);
        $res = json_decode($res, true);
    
        if(is_array($res)){
            if(isset($res['errcode'])){
                throw new Exception($res['errmsg']);
            } else {
                return $res;
            }
        } else {
            throw new Exception('获取微信access_token失败！');
        }
    }
    
    /**
     * 根据code获取getOpenId
     * @return array openid
     */
    public function getOpenId($code){
    
        if (empty($code)){
            throw new Exception('code不能为空！');
        }
    
        $param = array(
            'appid'         => $this->appId,
            'secret'        => $this->appSecret,
            'code'          => $code,
            'grant_type'    => 'authorization_code'
        );
         
        $url = "{$this->oauthApiURL}/oauth2/access_token";
    
        $res = $this->http($url, $param);
        $res = json_decode($res, true);
    
        if(is_array($res)){
            if(isset($res['errcode'])){
                throw new Exception($res['errmsg']);
            } else {
                return $res['openid'];
            }
        } else {
            throw new Exception('获取微信access_token失败！');
        }
    }
    
   
    
    /**
     * 获取授权用户信息
     * @param  string $code  
     * @param  string $lang  指定的语言
     * @return array         用户信息数据，具体参见微信文档
     */
    public function getUserInfo($code, $lang = 'zh_CN'){
        $token = $this->getAccessTokenByCode($code);       
        $query = array(
            'access_token' => $token['access_token'],
            'openid'       => $token['openid'],
            'lang'         => $lang,
        );

        $info = $this->http("{$this->oauthApiURL}/userinfo", $query);
        $info = json_decode($info, true);
        if(is_array($info)){
            if(isset($info['errcode'])){
                throw new Exception($info['errmsg']);
            } else {
                return $info;
            }
        } else {
            throw new Exception('获取失败！');
        }
        
    }
    
    
    /**
     * 创建用户组
     * @param  string $name 组名称
     */
    public function groupsCreate($name){
        $data = array('group' => array('name' => $name));
        return $this->api('groups/create', $data);
    }
    
    /**
     * 查询所有分组
     * @return array 分组列表
     */
    public function groupsGet(){
        return $this->api('groups/get', '', 'GET');
    }
    
    /**
     * 查询用户所在的分组
     * @param  string $openid 用户的OpenID
     * @return number         分组ID
     */
    public function groupsGetid($openid){
        $data = array('openid' => $openid);
        return $this->api('groups/getid', $data);
    }
    
    /**
     * 修改分组
     * @param  number $id   分组ID
     * @param  string $name 分组名称
     * @return array        修改成功或失败信息
     */
    public function groupsUpdate($id, $name){
        $data['group'] = array('id' => $id, 'name' => $name);
        return $this->api('groups/update', $data);
    }
    
    /**
     * 移动用户分组
     * @param  string $openid     用户的OpenID
     * @param  number $to_groupid 要移动到的分组ID
     * @return array              移动成功或失败信息
     */
    public function groupsMembersUpdate($openid, $to_groupid){
        $data = array('openid' => $openid, 'to_groupid' => $to_groupid);
        return $this->api('groups/members/update', $data);
    }
    
    /**
     * 批量移动用户分组
     * @param  array $openid_list     用户的OpenID列表
     * @param  number $to_groupid     要移动到的分组ID
     * @return array                  移动成功或失败信息
     */
    public function groupsMembersBatchupdate($openid_list, $to_groupid){
        $data = array('openid_list' => $openid_list, 'to_groupid' => $to_groupid);
        return $this->api('groups/members/batchupdate', $data);
    }
    
    /**
     * 删除用户分组，删除分组后，所有该分组内的用户自动进入默认分组
     * @param  string $group_id     分组id
     * @return array                删除成功或失败信息
     */
    public function groupsDelete($group_id){
        $data['group'] = array('id' => $group_id);
        return $this->api('groups/delete', $data);
    }
    
   
    
    /**
     * 用户设备注名
     * @param  string $openid 用户的OpenID
     * @param  string $remark 设备注名
     * @return array          执行成功失败信息
     */
    public function userInfoUpdateremark($openid, $remark){
        $data = array('openid' => $openid, 'remark' => $remark);
        return $this->api('User/info/updateremark', $data);
    }
    
    /**
     * 获取指定用户的详细信息
     * @param  string $openid 用户的openid
     * @param  string $lang   需要获取数据的语言
     */
    public function userInfo($openid, $lang = 'zh_CN'){
        $param = array('openid' => $openid, 'lang' => $lang);
        return $this->api('User/info', '', 'GET', $param);
    }
    
    /**
     * 获取关注者列表
     * @param  string $next_openid 第一个拉取的OPENID，在用户数大于10000时有效
     * @return array               用户列表
     */
    public function userGet($next_openid = ''){
        $param = array('next_openid' => $next_openid);
        return $this->api('User/get', '', 'GET', $param);
    }
    
    
    
}
